/*
 *  VariableRegistryTest.cpp
 *  MWorksCore
 *
 *  Created by David Cox on 4/11/06.
 *  Copyright 2006 __MyCompanyName__. All rights reserved.
 *
 */

#include "VariableRegistryTest.h"
#include "EventBuffer.h"


BEGIN_NAMESPACE_MW


CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( VariableRegistryTestFixture, "Unit Test" );


void VariableRegistryTestFixture::setUp(){
}

void VariableRegistryTestFixture::tearDown(){
}

void VariableRegistryTestFixture::testCodec(){
	VariableRegistry *r = new VariableRegistry(global_outgoing_event_buffer);

    Datum generated_codec(r->generateCodecDatum());	
	// #codec, #componentCodec, #termination (all generated by default)
	checkCodec(generated_codec, 0);
	CPPUNIT_ASSERT(r->getNVariables() == 0);
	
    Datum test1((float)5);
	VariableProperties props(test1,
							  "test",
							  "Test test",
							  "Testy test test test",
							  M_NEVER, 
							  M_WHEN_CHANGED,
							  true, 
							  false,
							  M_CONTINUOUS_INFINITE,
							  "");
	
	shared_ptr<Variable> testvar =
                r->createGlobalVariable(props);
	int n_variables = 1;
    
	CPPUNIT_ASSERT(r->lookupVariable("test").getInteger() == 5);
	CPPUNIT_ASSERT(r->getNVariables() == n_variables);
	
	
	//r->generateCodec();
    Datum generated_codec2(r->generateCodecDatum());
	
	checkCodec(generated_codec2, n_variables);
	
	shared_ptr<Variable> _testvar = r->getVariable("test");
	shared_ptr<Variable> __testvar = r->getVariable(N_RESERVED_CODEC_CODES);
    CPPUNIT_ASSERT(__testvar != NULL);
	CPPUNIT_ASSERT(_testvar->getValue() == testvar->getValue());
	CPPUNIT_ASSERT(__testvar->getValue() == testvar->getValue());

	CPPUNIT_ASSERT(r->hasVariable("test"));
	CPPUNIT_ASSERT(!r->hasVariable("test2"));
	CPPUNIT_ASSERT(r->getNVariables() == 1);
	
	// regenerate a new registry from the codec
	VariableRegistry *r2 = new VariableRegistry(global_outgoing_event_buffer);
	r2->updateFromCodecDatum(generated_codec2);
    Datum generated_codec3(r2->generateCodecDatum());
	checkCodec(generated_codec3, 1);

	CPPUNIT_ASSERT(r->lookupVariable("test").getInteger() == 5);
	CPPUNIT_ASSERT(r2->lookupVariable("test").getInteger() == 5);
	CPPUNIT_ASSERT(r->getNVariables() == n_variables);
	CPPUNIT_ASSERT(r2->getNVariables() == n_variables);
	
    Datum test2((long)15);
	VariableProperties props2(test2, 
							   "test2",
							   "Test2 test2",
							   "Testy test2 test2 test2",
							   M_NEVER, 
							   M_WHEN_CHANGED,
							   true, 
							   false,
							   M_CONTINUOUS_INFINITE,
							   "");
	shared_ptr<Variable> testvar2 =
            r2->createGlobalVariable(props2);
    
    n_variables++;
	
	_testvar = r2->getVariable("test");
	__testvar = r2->getVariable(N_RESERVED_CODEC_CODES);
	CPPUNIT_ASSERT(_testvar->getValue() == testvar->getValue());
	CPPUNIT_ASSERT(__testvar->getValue() == testvar->getValue());
	CPPUNIT_ASSERT(__testvar->getValue() == _testvar->getValue());
	shared_ptr<Variable> _testvar2 = r2->getVariable("test2");
	shared_ptr<Variable> __testvar2 = r2->getVariable(N_RESERVED_CODEC_CODES + 1);
	CPPUNIT_ASSERT(_testvar2->getValue() == testvar2->getValue());
	CPPUNIT_ASSERT(__testvar2->getValue() == testvar2->getValue());
	CPPUNIT_ASSERT(__testvar2->getValue() == _testvar2->getValue());

	CPPUNIT_ASSERT(r2->hasVariable("test"));
	CPPUNIT_ASSERT(r2->hasVariable("test2"));
	CPPUNIT_ASSERT(r2->getNVariables() == n_variables);

	CPPUNIT_ASSERT(r->lookupVariable("test").getInteger() == 5);
	CPPUNIT_ASSERT(r2->lookupVariable("test").getInteger() == 5);
	CPPUNIT_ASSERT(r2->lookupVariable("test2").getInteger() == 15);
	
    Datum generated_codec4(r2->generateCodecDatum());
	checkCodec(generated_codec4, 2);
	
	delete r;
	delete r2;
}


void VariableRegistryTestFixture::checkCodec(const Datum &generated_codec, int number_of_entries) const {
    CPPUNIT_ASSERT( generated_codec.isDictionary() );
    
    auto &dict = generated_codec.getDict();
    CPPUNIT_ASSERT( dict.size() == number_of_entries );
    
    for (auto &item : dict) {
        auto &key = item.first;
        auto &value = item.second;
        CPPUNIT_ASSERT( key.isInteger() );
        CPPUNIT_ASSERT( value.isDictionary() );
    }
}


END_NAMESPACE_MW

























